﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Resources;
using System.Windows.Forms;
using G.Runtime;
using GameDesigner.Displayers;
using GameDesigner.Source.Displayers;
using GameDesigner.Source.Widgets;
using GameLibrary.Model.Core;
using GameRuntimeLibrary.Model.Runtime.Actions;
using Microsoft.VisualBasic.PowerPacks;
using G.Runtime.Actions;

namespace GameDesigner.Source.Elements
{
    public class ElementDisplayerPT : ElementDisplayer
    {
        private readonly GameDisplayerPT _GameDisplayer;
        private readonly Game _Game;
        
        private Color _BackgroundColor = Color.WhiteSmoke;

        public ElementDisplayerPT(GameDisplayerPT displayer, SimpleShape shape,
            GameLocation point, ShapeContainer shapeContainer, Game pGame)
            : base(displayer, point, shape, shapeContainer)
        {
            _GameDisplayer = displayer;
            _Game = pGame;
            this.Shape.MouseClick += new MouseEventHandler(this.Shape_MouseClick);
            _Game.Elements.ElementPositionChangedEvent += this.OnElementPositionChanged;
            _Game.Elements.PropertyChangedEvent += delegate(GameElement subject) 
            {
                DisplayIcon();
            };
            DisplayIcon();
        }

        public override void DisplayIcon()
        {
            GameElement e = GetElement();
            if (e == null || e.Icon == "")
            {
                Shape.BackgroundImage = null;
                Shape.BackColor = _BackgroundColor;
                
                if (e != null && e.Text.Length > 0)
                {
                    DisplayText(ref e);
                }
            }
            else
            {
                ResourceSet set = global::GameDesigner.Properties.Resources.
                    ResourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, false);

                Bitmap image = (Bitmap)set.GetObject(e.Icon, true);
                Shape.BackgroundImage = image;
                Shape.BackgroundImageLayout = ImageLayout.Center;
                Shape.BackStyle = BackStyle.Opaque;

                if (_Game.Players.Contains(e.Player))
                {
                    GamePlayer player = _Game.Players[e.Player];
                    Shape.BackColor = player.Color;
                }
            }
        }

        void DisplayText(ref GameElement e)
        {
            Bitmap image = new Bitmap(50, 50);
            Graphics g = Graphics.FromImage(image);
            Font font = new Font("Comic Sans MS", 12);
            SolidBrush brush = new SolidBrush(Color.Black);
            Pen pen = new Pen(Color.LightGray, 1);
            g.DrawString(e.Text, font, brush, 0, 0);
            pen.Dispose();
            
            Shape.BackgroundImage = image;
            Shape.BackgroundImageLayout = ImageLayout.Center;
            Shape.BackStyle = BackStyle.Opaque;
        }
        
        private void Shape_MouseClick(Object target, EventArgs e)
        {
            SimpleShape shape = (SimpleShape)target;
            _GameDisplayer.MessagePanel.Clear();

            GameElement subject = null;
            if (_GameDisplayer.Game.Elements.Contains(
                new GameLocation(shape.Location)))
            {
                subject = _GameDisplayer.Game.Elements[
                    new GameLocation(shape.Location)];
            }

            if (subject is GameElement)
            {
                GameElement element = (GameElement)subject;
                _Game.Elements.Triggers.FireClickEvent(element);
                
                if (!_Game.GameController.ElementsReadyToMove.Contains(subject))
                {
                    subject = null;
                }
            }

            GameLocation location = new GameLocation(shape.Location);
            if (_GameDisplayer.Game.Elements.Actions.Contains(location))
            {
                GameElementAction action = _GameDisplayer.Game.Elements.Actions[location];
                action.Execute(_GameDisplayer.Game);
                ActiveObject.Object = null;
            }
            else if (subject is GameElement)
            {
                _GameDisplayer.Game.Elements.Actions.Clear();

                GameAction[] actions = subject.Actions.ToArray();
                foreach (GameAction action in actions)
                {
                    if (action is GameElementAction)
                    {
                        GameElementAction a = (GameElementAction)action;
                        _GameDisplayer.Game.Elements.Actions.Add(a);
                    }
                }
                
                ButtonPanel painter = _GameDisplayer.ButtonPanel;
                painter.Clear();
                foreach(GameTask task in subject.Game.GameTasks)
                {
                    painter.Add(_Game, task, subject);
                }
                
                ActiveObject.Object = subject;
            }
            else
            {
                _GameDisplayer.Game.Elements.Actions.Clear();
                ActiveObject.Object = null;
            }
        }

        private GameElement GetElement()
        {
            GameElement e = null;
            if (this._GameDisplayer.Game.Elements.Contains(Location))
            {
                e = this._GameDisplayer.Game.Elements[Location];
            }

            return e;
        }

        private void OnElementPositionChanged(GameLocation location)
        {
            if (base.Location == location)
            {
                DisplayIcon();
            }
        }

        private void OnPropertyChanged(object o, PropertyChangedEventArgs args)
        {
            DisplayIcon();
        }

    }

}
